package MonteCarloMonoThread;

import java.util.*;


public class MonteCarloSimulation {

	private String CallPutFlag; //"c" for call and "p" for put
	private double S,X,T,r,b,v;
	private int nSteps,nSimulations;
	
	
	public MonteCarloSimulation(String callPutFlag, double s, double x,
			double t, double r, double b, double v, int nSteps, int nSimulations) {
		super();
		CallPutFlag = callPutFlag;
		S = s;
		X = x;
		T = t;
		this.r = r;
		this.b = b;
		this.v = v;
		this.nSteps = nSteps;
		this.nSimulations = nSimulations;
	}
	
	public double Calculate(){
		double dt, St, Sum =0, Drift, vSqrdt;
		int i,j,z=0;
		Random random;
		
		dt = T / nSteps ;
		Drift = (b-v*v /2) * dt ;
		vSqrdt = v * java.lang.Math.sqrt(dt);
		
		if (CallPutFlag.equals("c"))z = 1;
		if (CallPutFlag.equals("p"))z = -1;
		
		for (i=0;i<nSimulations;i++) {
			St = S;
			random= new Random(5);
			for (j=0;j<nSteps;j++){
				St = St * java.lang.Math.exp(Drift + vSqrdt * random.nextGaussian());
			}
			Sum = Sum + Math.max(z * (St-X), 0);
		}
		return java.lang.Math.exp(-r * T) * (Sum / nSimulations);
		
	}
	
	public static void main (String [] args){
		MonteCarloSimulation mcs= new MonteCarloSimulation("c",40,50,0.5,0.06,0.10,0.45,168,100000);
		
		double timeStart = System.currentTimeMillis();
		
		System.out.println(mcs.Calculate());
		
		double timeEnd = System.currentTimeMillis();
		
		System.out.println("Time needed : " + (timeEnd-timeStart)/1000 + " s");
		
	}
	
	
}
